package com.example.kiratest.EasyExcel.Handler;

import jakarta.annotation.Resource;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Component
public class Test {



    //两个重要类，SqlsessionFactory和PlatformTransactionManager
    @Resource
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private PlatformTransactionManager transactionManager;


    public static final int CORE_POOL_SIZE = 5;
    public static final int MAX_POOL_SIZE = 10;
    public static final int QUEUE_CAPACITY = 100;
    public static final Long KEEP_ALIVE_TIME = 1L;

    public static final ThreadPoolExecutor kiraExecutor = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(QUEUE_CAPACITY),
            new ThreadPoolExecutor.AbortPolicy()
    );



    public void insert() {
    
        //状态变量，原子的Boolean类型防止多线程下出问题
        AtomicBoolean status = new AtomicBoolean(true);
        
        //countDwonLatch,我们有两个异步任务,当两个都执行完后我们的主线程再往下执行
        CountDownLatch countDownLatch = new CountDownLatch(2);
        
        //等两个事务都提交或回滚完我们再放行我们的主线程
        CountDownLatch waitCountDownLatch=new CountDownLatch(2);

        kiraExecutor.execute(() -> {

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
            try  {
                //我们要openSession设置为false,设置为手动提交
                SqlSession sqlSession = sqlSessionFactory.openSession(false);


//                手动抛出异常进行测试
//                throw new RuntimeException();
            } catch (Exception e) {
                status.set(false);
            } finally {
                countDownLatch.countDown();

            }

            try{
                countDownLatch.await();//等待所有的异步线程都执行完我们再提交
                if(status.get())
                {
                    transactionManager.commit(transaction);
                }
                else
                {
                    transactionManager.rollback(transaction);
                }

            }catch (Exception e)
            {

            }
            finally {
                waitCountDownLatch.countDown();
            }
        });


        kiraExecutor.execute(() -> {

            TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
            try  {

                //我们要openSession设置为false,设为手动提交
                SqlSession sqlSession = sqlSessionFactory.openSession(false);



            } catch (Exception e) {
                status.set(false);
            } finally {
                countDownLatch.countDown();
            }


            try{
                countDownLatch.await();//我们要所有的异步线程都执行完我们再提交
                if(status.get())
                {
                    transactionManager.commit(transaction);
                }
                else
                {
                    transactionManager.rollback(transaction);
                }

            }catch (Exception e)
            {

            }
            finally {
                waitCountDownLatch.countDown();
            }


        });


        try{
            waitCountDownLatch.await();//等待所有的异步线程都执行完我们的主线程才继续往下执行
        }
        catch (Exception e)
        {

        }



    }




}